import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

from main_tensorflow_01_model_define import CNNModel

# 加载MNIST数据集-在线文件下载
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 数据预处理
train_images, test_images = train_images / 255.0, test_images / 255.0  # 归一化到[0, 1]
train_images = train_images[..., np.newaxis]  # 增加一个通道维度
test_images = test_images[..., np.newaxis]

# 将标签转换为one-hot编码
train_labels = tf.keras.utils.to_categorical(train_labels, 10)
test_labels = tf.keras.utils.to_categorical(test_labels, 10)

# 创建 CNNModel 实例
cnn_model = CNNModel()
# 打印模型摘要
cnn_model.summary()
# 编译模型
cnn_model.compile()
# 训练模型
history = cnn_model.train(
    train_images.reshape(-1, 28, 28, 1),
    train_labels,
    epochs=5,
    batch_size=64,
    validation_data=(test_images.reshape(-1, 28, 28, 1), test_labels)
)

# 评估模型
test_loss, test_acc = cnn_model.evaluate(test_images.reshape(-1, 28, 28, 1), test_labels)
print(f'Test accuracy: {test_acc}')

# 保存模型
cnn_model.save('mnist_cnn_model_online.h5')

# 绘制训练和验证的损失曲线
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Loss over Epochs')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

# 绘制训练和验证的准确率曲线
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Accuracy over Epochs')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

# # 加载模型（可选）
# loaded_model = CNNModel.load('mnist_cnn_model.h5')
